home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / comm1 / s342q12.lha / ROqwk.c < prev    next >
C/C++ Source or Header  |  1996-03-28  |  38KB  |  1,532 lines

  1. /**
  2.  AsgQWK.c
  3.  QWIK off-line reader for Asgarde-86.  Modified for the Citadel 68K
  4.  
  5.  history
  6.  93Sep15 GSM  Created.
  7.  94OCT21 AFP  Modifications for Citadel-68K
  8.  
  9.  Contents
  10.  QWKmain              Main entry to QWK routines.
  11.  QWKUserConfig        QWK user configuration menu.
  12.  ScanRooms            Room selection menu.
  13.  UpdateLastRead
  14.  CreateQWKPacket
  15.  ExtractAndAdd
  16.  OkToSend
  17.  menus
  18.  qwkglobalreplace
  19.  qwkReadDate
  20.  qwkReadTime
  21.  RepReadDate
  22.  RepReadTime
  23.  ResetRooms
  24.  ArchQWK
  25.  CleanUpPacket
  26. **/
  27.  
  28. #include "ctdl.h"
  29.  
  30. #define VRSN           "V0.3c68k"
  31. int Zero;
  32. /**
  33.   external variable declarations in LOGEDIT.C
  34. **/
  35. /************************************************************************/
  36. extern CONFIG cfg;
  37. extern LogTable *logTab;          /* RAM index of pippuls */
  38. extern logBuffer logBuf;          /* Pippul buffer */
  39. extern aRoom roomBuf;
  40. extern MessageBuffer msgBuf;     /* Message buffer */
  41. extern MessageBuffer tempMess;   /* Message buffer */
  42. extern NetBuffer netBuf;
  43. extern rTable *roomTab;
  44. extern NetTable *netTab;
  45. extern FILE *logfl;               /* log file descriptor **/
  46. extern FILE *roomfl;
  47. extern FILE *netfl;
  48. extern struct floor *FloorTab;
  49. extern char NotForgotten;
  50. extern char onConsole;
  51. extern char haveCarrier;
  52. extern char outFlag;              /* will be one of the above */
  53. extern AN_UNSIGNED crtColumn;     /* where are we on screen now? */
  54. char noStop;
  55. extern long InChatTime;
  56. extern char loggedIn;
  57. extern int thisLog;
  58. extern char *READ_ANY;
  59. extern char FileTransStat;
  60. extern FILE *upfd;
  61. static char *MonthTab[] =
  62.   {
  63.   "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
  64.   "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"
  65.  
  66.   };
  67. SYS_FILE  tempname;
  68. SYS_FILE  tempFile;
  69. int       totconf,
  70. totfnd,
  71. tottoyou;
  72. unsigned char qwkbuf[128];
  73. long      currentsector;
  74. FILE     *qwkindfd,
  75. *qwkmsgfd,
  76. *qwkctlfd,
  77. *qwkpersfd;
  78. struct qwkheader
  79.   {
  80.   unsigned char status;
  81.   unsigned char number[7];
  82.   unsigned char date[8];
  83.   unsigned char time[5];
  84.   unsigned char to[25];
  85.   unsigned char from[25];
  86.   unsigned char subject[25];
  87.   unsigned char password[12];
  88.   unsigned char ref_no[8];
  89.   unsigned char size[6];
  90.   unsigned char active;
  91.   unsigned int conf;
  92.   unsigned int logical_msgno;
  93.   unsigned char nettag;
  94.  
  95.   };
  96. /*
  97. *
  98. * * the important stuff from the header
  99. */
  100. /*
  101. * true header format, only fields I use
  102. */
  103. struct qwkdefinition
  104.   {
  105.   char      YourOwn;
  106.   char      ResetBBSMsg;
  107.   char      NewFileScan;
  108.   char      FileDate[8];
  109.   char      Bulletins;
  110.   int       MaxPacket;
  111.   int       MaxRoom;
  112.   char      UpProtocol;
  113.   char      DownProtocol;
  114.   char      Archiver;
  115.   char      Hangafterupload;
  116.  
  117.   };
  118. struct qwkdefinition qwkdef;
  119. typedef struct
  120.   {
  121.   int       Selected;
  122.   MSG_NUMBER OldLastMessageNo;
  123.   MSG_NUMBER LastMessageNo;
  124.   MSG_NUMBER CurrentLastMessageNo;
  125.   int       AlternateConferenceNo;
  126.  
  127.   }
  128. QwkRoom;
  129. typedef struct
  130.   {
  131.   int       messagesfound;
  132.   int       messagestoyou;
  133.  
  134.   }
  135. UsedQwkRoom;
  136. QwkRoom  *QwkRooms;               /** RAM index of rooms */
  137. UsedQwkRoom *UsedQwkRooms;
  138. #ifdef ANSI_PROTOTYPING
  139. char      QWKmain(void);
  140. void      QWKUserConfig(void);
  141. void      ScanRooms(void);
  142. void      UpdateLastRead(void);
  143. void      CreateQWKPacket(void);
  144. void      ExtractAndAdd(int room);
  145. char      OkToSend(void);
  146. void      menus(void);
  147. void      qwkglobalreplace(char *buf, char *qwkold);
  148. void      qwkReadDate(char *date, char *datestr);
  149. void      qwkReadTime(char *time, char *timestr);
  150. void      RepReadDate(char *date, char *datestr);
  151. void      RepReadTime(char *time, char *timestr);
  152. void      ResetRooms(void);
  153. long      ArchQWK(void);
  154. void      InputREPPacket(void);
  155. void      ImportQWKPacket(void);
  156. void      CleanUpPacket(void);
  157. char      Process_Current_Message(SECTOR_ID  loc,MSG_NUMBER id);
  158. void      Jsystem(char *);
  159. float     FloatToMSB(float f);
  160. float     MSBtoFloat(float f);
  161. #endif
  162. /**
  163.   itoa(number,string,base);
  164.   number - number to convert to the requested base
  165.   string - destination string for number
  166.   base   - conversion base
  167. **/
  168. void itoa(int number, char *string, int base);
  169. void itoa(int number, char *string, int base)
  170.   {
  171.   sprintf(string,"%d",number);  /** cheap shortcut...*/
  172.   }
  173.  
  174.  
  175. /************************************************************************/
  176. /*
  177. * QWKmain() main controller.
  178. */
  179. /************************************************************************/
  180. char
  181. QWKmain()
  182.   {
  183.   FILE     *qwklogfd;
  184.   char      HasLog;
  185.   char      tempStr[20];
  186.   int       rover;
  187.   if( !cfg.BoolFlags.QwkMail )
  188.     {
  189.     Output_Citadel_Message("QWKNSP", NULL, NULL, NULL);
  190.     return GOOD_SELECT;
  191.     };
  192.   Output_Citadel_Message("QWKSUP",(LONG)VRSN, (LONG)COPYRIGHT, NULL);
  193.   if (!loggedIn)
  194.     {
  195.     Output_Citadel_Message("QWKLOG",NULL, NULL, NULL);
  196.     return GOOD_SELECT;
  197.     };
  198.   QwkRooms = (QwkRoom *) GetDynamic(MAXROOMS * (sizeof(*QwkRooms)));
  199.   UsedQwkRooms = (UsedQwkRoom *) GetDynamic(MAXROOMS * (sizeof(*UsedQwkRooms)));
  200.   HasLog = FALSE;
  201.   sprintf(tempStr, "qwklog.%03d", thisLog);
  202.   makeSysName(tempname, tempStr, &cfg.QwkFileArea);
  203.   if ((qwklogfd = fopen(tempname, "rb")) != NULL)
  204.     {
  205.     if (fread(&qwkdef, sizeof qwkdef, 1, qwklogfd) == 1)
  206.       {
  207.       HasLog = TRUE;
  208.       fread(QwkRooms, (sizeof(*QwkRooms)) * MAXROOMS, 1, qwklogfd);
  209.  
  210.       };
  211.     fclose(qwklogfd);
  212.  
  213.     };
  214.   if (HasLog == FALSE)
  215.     {
  216.     qwkdef.YourOwn = TRUE;
  217.     qwkdef.NewFileScan = FALSE;
  218.     strcpy(qwkdef.FileDate, "12/31/99");
  219.     qwkdef.Bulletins = FALSE;
  220.     qwkdef.MaxPacket = cfg.QwkMaxPacket;
  221.     qwkdef.MaxRoom =   cfg.QwkMaxRooms;
  222.     qwkdef.UpProtocol = 'X';            /* Xmodem is always the default */
  223.     qwkdef.DownProtocol = 'X';
  224.     qwkdef.Archiver = 1;
  225.     qwkdef.Hangafterupload = FALSE;
  226.     for (rover = 0; rover < MAXROOMS; rover++)
  227.       {
  228.       QwkRooms[rover].Selected = 0;
  229.       QwkRooms[rover].OldLastMessageNo = 0l;
  230.       QwkRooms[rover].LastMessageNo =
  231.       logBuf.lbvisit[logBuf.lbgen[rover] & CALLMASK];
  232.       QwkRooms[rover].CurrentLastMessageNo = 0l;
  233.       QwkRooms[rover].AlternateConferenceNo = 0;
  234.  
  235.       };
  236.  
  237.     };
  238.   menus();
  239.   sprintf(tempStr, "qwklog.%03d", thisLog);
  240.   makeSysName(tempname, tempStr, &cfg.QwkFileArea);
  241.   if ((qwklogfd = fopen(tempname, "wb")) != NULL)
  242.     {
  243.     if (fwrite(&qwkdef, sizeof qwkdef, 1, qwklogfd) == 1)
  244.       {
  245.       fwrite(QwkRooms, (sizeof(*QwkRooms)) * MAXROOMS, 1, qwklogfd);
  246.       };
  247.     fclose(qwklogfd);
  248.     }
  249.   free(QwkRooms);
  250.   free(UsedQwkRooms);
  251.   getRoom(LOBBY);
  252.   return GOOD_SELECT;
  253.  
  254.   }
  255. /************************************************************************/
  256. /*
  257. * QWKUserConfig() various settings for users.
  258. */
  259. /************************************************************************/
  260. void
  261. QWKUserConfig()
  262.   {
  263.   char      done = FALSE;
  264.   char      letter,
  265.   letter1;
  266.   char *protocol;
  267.   do
  268.     {
  269.     Output_Citadel_Message("QWKCFG",NULL, NULL, NULL);
  270.     Output_Citadel_Message("QWKCR1"
  271.       ,(long)(qwkdef.YourOwn ? "Yes" : "No")
  272.       ,(long)(qwkdef.Hangafterupload ? "Yes" : "No"), NULL);
  273.     Output_Citadel_Message("QWKCR2", qwkdef.MaxPacket, qwkdef.MaxRoom, NULL);
  274.     switch ( qwkdef.DownProtocol )
  275.       {
  276.       case 'X': protocol = "XMODEM"; break;
  277.       case 'Y': protocol = "YMODEM"; break;
  278.       default:
  279.        protocol = FindProtoName(qwkdef.DownProtocol);
  280.        if( protocol == NULL )
  281.          {
  282.          protocol = "XMODEM";
  283.          qwkdef.DownProtocol = 'X';
  284.          };
  285.       };
  286.     Output_Citadel_Message("QWKCR3",(long)protocol
  287.       ,(long)GetCompEnglish(qwkdef.Archiver), NULL);
  288.     /**
  289.     sessioncheck = 0;
  290.       chkTimeSince(USER_SESSION) - InChatTime;
  291.     if (sessionLimit > 0)
  292.     mPrintf("You have been on for %lu minutes, and have %lu minutes left.\n ",
  293.     (sessioncheck / 60), (((sessionLimit * 60) - sessioncheck) / 60));
  294.     **/
  295.     Output_Citadel_Message("QWKCR4", NULL, NULL, NULL);
  296.     letter1 = toUpper(iChar());
  297.     mPrintf("\n ");
  298.     switch (letter1)
  299.       {
  300.       case 'C':      ScanRooms();      break;
  301.       case 'R':      ResetRooms();     break;
  302.       case 'S':      qwkdef.YourOwn = !qwkdef.YourOwn; break;
  303.       case 'T':
  304.       Output_Citadel_Message("QWKCR5",NULL, NULL, NULL);
  305.       letter = toUpper(iChar());
  306.       mPrintf("\n ");
  307.       if ((qwkdef.DownProtocol = FindProtocolCode(letter, FALSE)) == -1)
  308.         {
  309.         if( letter != 'X' && letter != 'Y' )
  310.           {
  311.           mPrintf("invalid protocol, setting to Xmodem\n ");
  312.           qwkdef.DownProtocol = 'X';
  313.           }
  314.         else qwkdef.DownProtocol = letter;
  315.         }
  316.       break;
  317.       case 'P':      qwkdef.Archiver = GetUserCompression();  break;
  318.       /*
  319.       * case 'D':  break;
  320.       */
  321.       case 'M':
  322.       qwkdef.MaxPacket = getNumber("QWKTMS", 0, cfg.QwkMaxPacket);
  323.       qwkdef.MaxRoom   = getNumber("QWKMPC", 0, cfg.QwkMaxRooms);
  324.       break;
  325.       case 'G': qwkdef.Hangafterupload = !qwkdef.Hangafterupload;  break;
  326.       /**
  327.         case 'F':  mPrintf("Not used at this time\n "); break;
  328.       **/
  329.       case '?':
  330.       case 'H':    Output_Citadel_Message("QCFHLP", NULL, NULL, NULL);    break;
  331.       case 'Q':    done = TRUE;    break;
  332.       default:
  333.       done = TRUE;
  334.       break;
  335.  
  336.       }
  337.     if (!done)
  338.     writeSysTab();
  339.  
  340.     }
  341.   while (!done);
  342.  
  343.   }
  344. /************************************************************************/
  345. /*
  346. * ScanRooms() Room selection setup routine.
  347. */
  348. /************************************************************************/
  349. #define ALL 0
  350. #undef  SELECTED
  351. #define SELECTED 1
  352. void
  353. ScanRooms()
  354.   {
  355.   int       rover,
  356.   currentstart,
  357.   i,
  358.   newstart,
  359.   done,
  360.   innerdone,
  361.   lpcnt;
  362.   int       lines,
  363.   pagelength,
  364.   chosen;
  365.   char      tempStr[10],
  366.   scanflag,
  367.   letter[5];
  368.   newstart = 0;
  369.   currentstart = 0;
  370.   i = 0;
  371.   /*  if (logBuf.lbscrnlngth == 0) */
  372.   pagelength = 23;
  373.   /*  else
  374.   pagelength = logBuf.lbscrnlngth;
  375.   */
  376.   done = FALSE;
  377.   scanflag = ALL;
  378.   do
  379.     {
  380.     lines = 0;
  381.     for (rover = currentstart; rover < MAXROOMS; rover++)
  382.       {
  383.       /*
  384.       * deep breath ... should rewrite this, prime example of programming
  385.       * via accretion.
  386.       */
  387.       if ((KnownRoom(rover) || (NotForgotten &&
  388.       roomTab[rover].rtflags.INUSE &&
  389.       (aide && (cfg.BoolFlags.aideSeeAll || onConsole) &&
  390.       (!roomTab[rover].rtflags.INVITE || onConsole)))))
  391.         {
  392.         if (QwkRooms[rover].Selected)
  393.         sprintf(tempStr, "(%7.7lu)", QwkRooms[rover].LastMessageNo);
  394.         else
  395.         memset(tempStr, NULL, 7);
  396.         if ((scanflag == SELECTED && QwkRooms[rover].Selected) ||
  397.         (scanflag == ALL))
  398.           {
  399.           mPrintf("%3d)%s%-20s %9s ", rover,(QwkRooms[rover].Selected ? "*" : " "),
  400.           roomTab[rover].rtname, tempStr);
  401.           i++;
  402.           if (i == 2)
  403.             {
  404.             mPrintf("\n ");
  405.             i = 0;
  406.             lines = lines + 1;
  407.  
  408.             }
  409.           if (lines == (pagelength - 5))
  410.             {
  411.             newstart = rover + 1;
  412.             rover = MAXROOMS;
  413.  
  414.             }
  415.  
  416.           }
  417.  
  418.         }
  419.  
  420.       }
  421.     innerdone = FALSE;
  422.     do
  423.       {
  424.       /**
  425.         mPrintf("You have been on for %d minutes, and have %d minutes left.\n ", ontime, maxtime);
  426.       **/
  427.       if (newstart < MAXROOMS)Output_Citadel_Message("QWKCC1",NULL, NULL, NULL);
  428.       Output_Citadel_Message("QWKCCL",NULL, NULL, NULL);
  429.       getString("", letter, 5, 0);
  430.       if (strlen(letter) == 0)
  431.       letter[0] = '?';
  432.       for (lpcnt = 0; lpcnt < strlen(letter); lpcnt++)
  433.       letter[lpcnt] = toUpper(letter[lpcnt]);
  434.       mPrintf("\n ");
  435.       switch (letter[0])
  436.         {
  437.         case 'T':
  438.         currentstart = 0;
  439.         innerdone = TRUE;
  440.         break;
  441.         case '+':
  442.         currentstart = newstart;
  443.         if (currentstart > MAXROOMS)
  444.         currentstart = MAXROOMS - (pagelength - 5);
  445.         innerdone = TRUE;
  446.         break;
  447.         case '-':
  448.         currentstart = currentstart - (pagelength - 5);
  449.         if (currentstart < 0)
  450.         currentstart = 0;
  451.         innerdone = TRUE;
  452.         break;
  453.         case 'L':        innerdone = TRUE;        break;
  454.         case 'A':        scanflag = ALL;          break;
  455.         case 'O':        scanflag = SELECTED;     break;
  456.         case 'Q':  done = TRUE; innerdone = TRUE; break;
  457.         case '*':
  458.         case 'R':
  459.         for (chosen = 0; chosen < MAXROOMS; chosen++)
  460.           {
  461.           if (KnownRoom(chosen) ||
  462.           (NotForgotten && roomTab[chosen].rtflags.INUSE &&
  463.           (aide && (cfg.BoolFlags.aideSeeAll || onConsole)) &&
  464.           (!roomTab[chosen].rtflags.INVITE || onConsole)))
  465.             {
  466.             if (!QwkRooms[chosen].Selected || letter[0] == '*')
  467.             QwkRooms[chosen].Selected = TRUE;
  468.             else
  469.             QwkRooms[chosen].Selected = FALSE;
  470.  
  471.             }
  472.  
  473.           }
  474.         break;
  475.         case '?':
  476.           Output_Citadel_Message("QWKCLH",NULL, NULL, NULL);
  477.         break;
  478.         default:
  479.         /*
  480.         * chosen = getNumber("QWKRMN", 0, MAXROOMS);
  481.         */
  482.         chosen = (int) atoi(letter);
  483.         if (KnownRoom(chosen) ||
  484.         (NotForgotten && roomTab[chosen].rtflags.INUSE &&
  485.         (aide && (cfg.BoolFlags.aideSeeAll || onConsole)) &&
  486.         (!roomTab[rover].rtflags.INVITE || onConsole)))
  487.           {
  488.           if (QwkRooms[chosen].Selected)
  489.           QwkRooms[chosen].Selected = FALSE;
  490.           else
  491.           QwkRooms[chosen].Selected = TRUE;
  492.  
  493.           }
  494.         else
  495.           {
  496.           mPrintf("Room(conference) not known or not in use.\n ");
  497.  
  498.           }
  499.         break;
  500.  
  501.         }
  502.  
  503.       }
  504.     while (!innerdone);
  505.  
  506.     }
  507.   while (!done);
  508.  
  509.   }
  510. /**
  511.  UpdateLastRead() Updates QWK message pointer structure.  Called
  512.  only after a succesful download.
  513. **/
  514. void
  515. UpdateLastRead()
  516.   {
  517.   int       rover;
  518.   for (rover = 0; rover < MAXROOMS; rover++)
  519.     {
  520.     if (UsedQwkRooms[rover].messagesfound > 0)
  521.       {
  522.       QwkRooms[rover].OldLastMessageNo = QwkRooms[rover].LastMessageNo;
  523.       QwkRooms[rover].LastMessageNo = QwkRooms[rover].CurrentLastMessageNo;
  524.       QwkRooms[rover].CurrentLastMessageNo = 0l;
  525.  
  526.       }
  527.  
  528.     }
  529.  
  530.   }
  531. /**
  532. CreateQWKPacket()
  533. Scans all rooms for new messages and extracts them IF the room is selected.
  534. **/
  535. void
  536. CreateQWKPacket()
  537.   {
  538.   int       rover;
  539.   int       year,  month,  day,  hours,  minutes,  seconds,  milli;
  540.   int         success;
  541.   char      tempstr[30],  tempstr2[30],  c, *tempc;
  542.   char *protocol;
  543.   long      packetSize;
  544.   getRawDate(&year, &month, &day, &hours, &minutes,
  545.   &seconds, &milli);
  546.   makeSysName(tempname, "messages.dat", &cfg.QwkWorkArea);
  547.   if ((qwkmsgfd = fopen(tempname, "wb")) == NULL)
  548.     {
  549.     crashout("Cannot Open messages data file!");
  550.  
  551.     }
  552.   memset(qwkbuf, ' ', 128);
  553.   sprintf(qwkbuf, "Produced by QMAIL...Copyright (c) 1987 by Sparkware. All Rights Reserved.");
  554.   success = strlen(qwkbuf);
  555.   qwkbuf[success] = ' ';
  556.   fwrite(qwkbuf, 128, 1, qwkmsgfd);
  557.   currentsector = 1;
  558.   makeSysName(tempname, "personal.ndx", &cfg.QwkWorkArea);
  559.   if ((qwkpersfd = fopen(tempname, "wb")) == NULL)
  560.     {
  561.     crashout("Cannot Open personal.ndx data file!");
  562.  
  563.     }
  564.   makeSysName(tempname, "control.dat", &cfg.QwkWorkArea);
  565.   if ((qwkctlfd = fopen(tempname, "wb")) == NULL)
  566.     {
  567.     crashout("Cannot Open control data file!");
  568.  
  569.     }
  570.   fputs((cfg.codeBuf + cfg.nodeName), qwkctlfd);
  571.   fputc('\r', qwkctlfd);
  572.   fputc(NEWLINE, qwkctlfd);
  573.   if( ( tempc = strchr(cfg.QwkLocation.saDirname,'/')) )*tempc = '\0';
  574.   fputs(cfg.QwkLocation.saDirname, qwkctlfd);
  575.   fputc('\r', qwkctlfd);
  576.   fputc(NEWLINE, qwkctlfd);
  577.   fputs((cfg.nodeId + cfg.codeBuf), qwkctlfd);
  578.   fputc('\r', qwkctlfd);
  579.   fputc(NEWLINE, qwkctlfd);
  580.   fputs(cfg.SysopName, qwkctlfd);
  581.   fputc('\r', qwkctlfd);
  582.   fputc(NEWLINE, qwkctlfd);
  583.   sprintf(tempstr, "0,%s", (cfg.codeBuf + cfg.nodeTitle));
  584.   fputs(tempstr, qwkctlfd);
  585.   fputc('\r', qwkctlfd);
  586.   fputc(NEWLINE, qwkctlfd);
  587.   sprintf(tempstr, "%02d-%02d-%04d,%02d:%02d:%02d", month, day, year,
  588.   hours, minutes, seconds);
  589.   fputs(tempstr, qwkctlfd);
  590.   fputc('\r', qwkctlfd);
  591.   fputc(NEWLINE, qwkctlfd);
  592.   sprintf(tempstr, "%s", strupr(logBuf.lbname));
  593.   fputs(tempstr, qwkctlfd);
  594.   fputc('\r', qwkctlfd);
  595.   fputc(NEWLINE, qwkctlfd);
  596.   fputs(" ", qwkctlfd);
  597.   fputc('\r', qwkctlfd);
  598.   fputc(NEWLINE, qwkctlfd);
  599.   fputs("0", qwkctlfd);
  600.   fputc('\r', qwkctlfd);
  601.   fputc(NEWLINE, qwkctlfd);
  602.   mPrintf("\n Preparing mail packet...\n ");
  603.   mPrintf("Press S to abort scan\n \n ");
  604.   mPrintf("Total message limit: %d\n ", qwkdef.MaxPacket);
  605.   mPrintf("Room(Conference) message limit: %d\n ", qwkdef.MaxRoom);
  606.   mPrintf("                                          High    Last    Number      To\n ");
  607.   mPrintf(" Number  Conference                    Message    Read     Found     You\n ");
  608.   mPrintf("------------------------------------------------------------------------\n ");
  609.   totfnd = 0;
  610.   totconf = 0;
  611.   outFlag = OUTOK;
  612.   for (rover = 0; rover < MAXROOMS && onLine() && outFlag == OUTOK; rover++)
  613.     {
  614.     if (rover == MAILROOM)
  615.       {
  616.       getRoom(rover);
  617.       fillMailRoom();   /* update room also  */
  618.  
  619.       }
  620.     UsedQwkRooms[rover].messagesfound = 0;
  621.     UsedQwkRooms[rover].messagestoyou = 0;
  622.     if (QwkRooms[rover].Selected && roomTab[rover].rtflags.INUSE)
  623.       {
  624.       mPrintf("   %3d     %-20s        %7.7lu %7.7lu ", rover,
  625.       roomTab[rover].rtname, roomTab[rover].rtlastMessage,
  626.       QwkRooms[rover].LastMessageNo);
  627.       ExtractAndAdd(rover);
  628.       mPrintf("    %5d   %5d\n ", UsedQwkRooms[rover].messagesfound,
  629.       UsedQwkRooms[rover].messagestoyou);
  630.       tottoyou += UsedQwkRooms[rover].messagestoyou;
  631.       mAbort();
  632.  
  633.       }
  634.  
  635.     }
  636.   if (outFlag == OUTOK)
  637.     {
  638.     mPrintf("Total messages found: %d\n ", totfnd);
  639.     }
  640.   sprintf(tempstr, "%d", totfnd);
  641.   fputs(tempstr, qwkctlfd);
  642.   fputc('\r', qwkctlfd);
  643.   fputc(NEWLINE, qwkctlfd);
  644.   sprintf(tempstr, "%d", totconf - 1);
  645.   fputs(tempstr, qwkctlfd);
  646.   fputc('\r', qwkctlfd);
  647.   fputc(NEWLINE, qwkctlfd);
  648.   for (rover = 0; rover < MAXROOMS; rover++)
  649.     {
  650.     if (UsedQwkRooms[rover].messagesfound != 0)
  651.       {
  652.       sprintf(tempstr, "%d", rover);
  653.       fputs(tempstr, qwkctlfd);
  654.       fputc('\r', qwkctlfd);
  655.       fputc(NEWLINE, qwkctlfd);
  656.       fputs(roomTab[rover].rtname, qwkctlfd);
  657.       fputc('\r', qwkctlfd);
  658.       fputc(NEWLINE, qwkctlfd);
  659.  
  660.       }
  661.  
  662.     }
  663.   fputs("BULLETIN.QWK", qwkctlfd);
  664.   fputc('\r', qwkctlfd);
  665.   fputc(NEWLINE, qwkctlfd);
  666.   fputs("NEWS.QWK", qwkctlfd);
  667.   fputc('\r', qwkctlfd);
  668.   fputc(NEWLINE, qwkctlfd);
  669.   fputs("GOODBYE.QWK", qwkctlfd);
  670.   fputc('\r', qwkctlfd);
  671.   fputc(NEWLINE, qwkctlfd);
  672.   fclose(qwkctlfd);
  673.   fclose(qwkmsgfd);
  674.   fclose(qwkpersfd);
  675.   if (outFlag == OUTOK && totfnd > 0)
  676.     {
  677.     mPrintf("Would you like to receive this packet,\n ");
  678.     mPrintf("[Y]es, [N]o, [G]oodbye when done? ");
  679.     c = toUpper(iChar());
  680.     mPrintf("\n ");
  681.     switch (c)
  682.       {
  683.       case 'Y':
  684.       case 'G':
  685.       mPrintf("Packing QWK packet with %s\n ", GetCompEnglish(qwkdef.Archiver));
  686.       packetSize = ArchQWK();
  687.       mPrintf("Packet size: %lu bytes\n ", packetSize);
  688.       sprintf(tempstr, "%s.qwk", cfg.QwkName.saDirname);
  689.       if( !onConsole )
  690.         {
  691.        if( qwkdef.DownProtocol == 'X' )
  692.          {
  693.          protocol = "XMODEM";
  694.          }
  695.        else if( qwkdef.DownProtocol == 'Y' )
  696.          {
  697.          protocol = "YMODEM";
  698.          }
  699.        else
  700.          {
  701.          protocol = FindProtoName(qwkdef.DownProtocol);
  702.          if( protocol == NULL )
  703.            {
  704.            protocol = "XMODEM";
  705.            qwkdef.DownProtocol = 'X';
  706.            };
  707.          };
  708.         mPrintf("Start your %s download now\n ",protocol);
  709.         };
  710.       strcpy(tempstr2, cfg.QwkWorkArea.saDirname);
  711.       success = strlen(tempstr2);
  712.       tempstr2[success - 1] = NULL;
  713.       if( cfg.BoolFlags.debug )  printf("%s\n", tempstr2);
  714.       if (chdir(tempstr2) != 0) printf("chdir failed!\n");
  715.       if( cfg.BoolFlags.debug )  printf("%s\n", getcwd(NULL, 100));;
  716.       if( onConsole )
  717.         {
  718.         char buf[128];
  719.         char tmp[40];
  720.         getString("GTQWKD",tmp,40,0);
  721.         sPrintf(buf,"copy >NIL: %s %s",tempstr,tmp);
  722.         Jsystem(buf);
  723.         FileTransStat = FL_SUCCESS;
  724.         }
  725.       else
  726.         {
  727.         FileTransStat = FL_START;
  728.         TranFiles(qwkdef.DownProtocol,  FALSE);
  729.         };
  730.       if (c == 'G')  HangUp(TRUE);
  731.       if( cfg.BoolFlags.debug ) printf("%d\n", FileTransStat);
  732.       if (FileTransStat == FL_SUCCESS)  UpdateLastRead();
  733.       break;
  734.  
  735.       }
  736.  
  737.     }
  738.   outFlag = OUTOK;
  739.   CleanUpPacket();
  740.   homeSpace();
  741.  
  742.   }
  743. /**
  744.  ExtractAndAdd() Reads the selected room for new messages and
  745.  
  746.  
  747.  places them in the QWK packet in proper format.
  748. **/
  749. #define LOADIT !NORMAL
  750. void
  751. ExtractAndAdd(int room)
  752.   {
  753.   float record_number;
  754.   struct qwkheader qwkhead;
  755.   int    length,  chrcnt,  blocks,  tempcheck,  tc;
  756.   SYS_FILE  tempname;
  757.   char     *mp;
  758.   char      nwlcp = (signed char)227;
  759.   int       i,count,  h,  j,  start,  finish;
  760.   MSG_NUMBER lowLim,  highLim,  msgNo,  MsgRead;
  761.   char        tempstr[50], conf, *fix1, *fix2;
  762.   getRoom(room);
  763.   if (room == MAILROOM)
  764.   fillMailRoom();       /*
  765.   * update room also
  766.   */
  767.   start = 0;
  768.   finish = (room == MAILROOM) ? MAILSLOTS : MSGSPERRM;
  769.   lowLim = QwkRooms[room].LastMessageNo + 1l;
  770.   highLim = cfg.newest;
  771.   if (cfg.oldest > lowLim)
  772.     {
  773.     lowLim = cfg.oldest;
  774.  
  775.     }
  776.   MsgRead = lowLim;
  777.   sprintf(tempstr, "%03d.ndx", room);
  778.   makeSysName(tempname, tempstr, &cfg.QwkWorkArea);
  779.   if ((qwkindfd = fopen(tempname, "wb")) == NULL)
  780.     {
  781.     sprintf(tempstr, "Cannot create index file for conference %d", room);
  782.     crashout(tempstr);
  783.  
  784.     }
  785.   for (i = start; i != finish && (onLine()) &&
  786.   totfnd < qwkdef.MaxPacket && outFlag == OUTOK &&
  787.   UsedQwkRooms[room].messagesfound < qwkdef.MaxRoom; i++)
  788.     {
  789.     msgNo = (roomBuf.msg[i].rbmsgNo & S_MSG_MASK);
  790.     /**
  791.     * Now check to see if msg is in "to be read" range, OR if we are
  792.     * reading New AND the message is marked as SKIPPED (only happens in
  793.     * Mail).  Note at the moment we're not going to worry about net mode --
  794.     * we don't use this loop for sending Mail, although we do for other
  795.     * rooms.
  796.     */
  797.     if (
  798.     (msgNo >= lowLim && highLim >= msgNo)
  799.     )
  800.       {
  801.       noStop = LOADIT;
  802.       if ( Process_Current_Message(roomBuf.msg[i].rbmsgLoc, msgNo) &&
  803.         OkToSend())
  804.         {
  805.         noStop = NORMAL;
  806.         UsedQwkRooms[room].messagesfound++;
  807.         if (msgNo > MsgRead)
  808.         MsgRead = msgNo;
  809.         totfnd++;
  810.         memset(&qwkhead, ' ', 128);
  811.         sprintf(tempstr, "/\n /%c/", 227);
  812.         qwkglobalreplace(msgBuf.mbtext, tempstr);
  813.         sprintf(tempstr, "/\n/%c/", ' ');
  814.         qwkglobalreplace(msgBuf.mbtext, tempstr);
  815.         length = strlen(msgBuf.mbtext);
  816.         length = (length / 79) + length;
  817.         blocks = (length / 128) + 2;
  818.         qwkhead.status = ' ';
  819.         itoa(totfnd, qwkhead.number, 10);
  820.         tempcheck = strlen(qwkhead.number);
  821.         qwkhead.number[tempcheck] = ' ';
  822.         qwkReadDate(msgBuf.mbdate, qwkhead.date);
  823.         tempcheck = strlen(qwkhead.date);
  824.         qwkhead.date[tempcheck] = ' ';
  825.         qwkReadTime(msgBuf.mbtime, qwkhead.time);
  826.         tempcheck = strlen(qwkhead.time);
  827.         qwkhead.time[tempcheck] = ' ';
  828.         if (!msgBuf.mbto[0])
  829.         strcpy(qwkhead.to, "ALL");
  830.         else
  831.         strncpy(qwkhead.to, strupr(msgBuf.mbto), 25);
  832.         tempcheck = strlen(qwkhead.to);
  833.         qwkhead.to[tempcheck] = ' ';
  834.         if (strcmpi(msgBuf.mbto, logBuf.lbname) == SAMESTRING)
  835.         UsedQwkRooms[room].messagestoyou++;
  836.         if (!roomBuf.rbflags.ANON)
  837.           {
  838.           strncpy(qwkhead.from, strupr(msgBuf.mbauth),24);
  839.           qwkhead.from[24] = '\0';     /* prevent long name problems */
  840.           tempcheck = strlen(qwkhead.from);
  841.           qwkhead.from[tempcheck] = ' ';
  842.  
  843.           }
  844.  /**
  845.         strncpy(qwkhead.subject, msgBuf.mbSubj, 25);
  846.  **/
  847.         strcpy(qwkhead.subject, roomBuf.rbname);
  848.         qwkhead.subject[20] = '\0';
  849.         tempcheck = strlen(qwkhead.subject);
  850.         qwkhead.subject[tempcheck] = ' ';
  851.         memset(qwkhead.password, ' ', 12);
  852.         itoa(UsedQwkRooms[room].messagesfound, qwkhead.ref_no, 10);
  853.         tempcheck = strlen(qwkhead.ref_no);
  854.         qwkhead.ref_no[tempcheck] = ' ';
  855.         itoa(blocks, qwkhead.size, 10);
  856.         tempcheck = strlen(qwkhead.size);
  857.         qwkhead.size[tempcheck] = ' ';
  858.         qwkhead.active = 225;
  859.         fix1 = (char *)&room;
  860.         fix2 = (char *)&qwkhead.conf;
  861.         fix2[0] = fix1[1];
  862.         fix2[1] = fix1[0];
  863.         fix1 = (char *)&totfnd;
  864.         fix2 = (char *)&qwkhead.logical_msgno;
  865.         fix2[0] = fix1[1];
  866.         fix2[1] = fix1[0];
  867.         qwkhead.nettag = ' ';
  868.         currentsector++;
  869.         fwrite(&qwkhead, 128, 1, qwkmsgfd);
  870.         record_number = (float) currentsector;
  871.         record_number = FloatToMSB(record_number);
  872.         fix1 = (char *)&record_number;
  873.         for(count=3; count >= 0; count--)fputc(fix1[count],qwkindfd);
  874.         conf = (char) ( room & 0xFF );
  875.         fputc(conf,  qwkindfd);
  876.         if( msgBuf.mbto[0] != '\0')
  877.           {
  878.           if (strcmpi(msgBuf.mbto, logBuf.lbname) == SAMESTRING)
  879.             {
  880.             fix1 = (char *)&record_number;
  881.             for(count=3; count >= 0; count--)fputc(fix1[count],qwkpersfd);
  882.             conf = (char) ( room & 0xFF );
  883.             fputc(conf,  qwkpersfd);
  884.  
  885.             };
  886.           };
  887.         mp = msgBuf.mbtext;
  888.         chrcnt = 0;
  889.         for (h = 1; h < blocks; h++)
  890.           {
  891.           memset(qwkbuf, ' ', 128);
  892.           for (j = 0; j < 128; j++)
  893.             {
  894.             if (*mp != NULL)
  895.               {
  896.               if (*mp == nwlcp)
  897.               chrcnt = 0;
  898.               if (j < 128)
  899.                 {
  900.                 qwkbuf[j] = *mp;
  901.                 chrcnt++;
  902.                 mp++;
  903.  
  904.                 }
  905.               if (chrcnt == 79)
  906.                 {
  907.                 tc = j;
  908.                 do
  909.                   {
  910.                   if (tc >= 0 && qwkbuf[tc] == ' ')
  911.                     {
  912.                     qwkbuf[tc] = 227;
  913.                     chrcnt = 0;
  914.  
  915.                     }
  916.                   else
  917.                     {
  918.                     chrcnt--;
  919.                     tc--;
  920.  
  921.                     }
  922.                   if (chrcnt == 45)
  923.                     {
  924.                     j++;
  925.                     qwkbuf[j] = 227;
  926.                     chrcnt = 0;
  927.  
  928.                     }
  929.  
  930.                   }
  931.                 while (chrcnt > 44);
  932.  
  933.                 }
  934.  
  935.               }
  936.             else
  937.               {
  938.               qwkbuf[j] = 227;
  939.               break;
  940.  
  941.               }
  942.  
  943.             }
  944.           fwrite(qwkbuf, 128, 1, qwkmsgfd);
  945.           currentsector++;
  946.  
  947.           }
  948.  
  949.         }
  950.  
  951.       }
  952.  
  953.     }
  954.   fclose(qwkindfd);
  955.   noStop = NORMAL;
  956.   if (UsedQwkRooms[room].messagesfound == 0)
  957.     {
  958.     sprintf(tempstr, "%03d.ndx", room);
  959.     makeSysName(tempname, tempstr, &cfg.QwkWorkArea);
  960.     unlink(tempname);
  961.  
  962.     }
  963.   else
  964.     {
  965.     totconf++;
  966.     QwkRooms[room].CurrentLastMessageNo = MsgRead;
  967.  
  968.     }
  969.  
  970.   }
  971. /**
  972. OkToSend() Checks the current message to make sure it is a
  973. selected message to be sent.
  974. **/
  975. char
  976. OkToSend()
  977.   {
  978.   /*
  979.   * if ((strcmpi(msgBuf.mbauth, logBuf.lbname)==SAMESTRING) &&
  980.   * qwkdef.YourOwn)
  981.  return TRUE;
  982.   */
  983.   if ((strcmpi(msgBuf.mbauth, logBuf.lbname) == SAMESTRING) &&
  984.   !qwkdef.YourOwn)
  985.   return FALSE;
  986.   return TRUE;
  987.  
  988.   }
  989. /**
  990.  menus() Main menu routine.
  991. **/
  992. void
  993. menus()
  994.   {
  995.   char      letter,
  996.   done = FALSE;
  997.   do
  998.     {
  999.     outFlag = OUTOK;
  1000.     Output_Citadel_Message("QWKMNM", NULL, NULL, NULL);
  1001.     letter = toUpper(iChar());
  1002.     mPrintf("\n ");
  1003.     switch (letter)
  1004.       {
  1005.       case 'C':      QWKUserConfig();                  break;
  1006.       case 'D':      CreateQWKPacket();                break;
  1007.       case 'H':      Output_Citadel_Message("QWKHLP", NULL, NULL, NULL); break;
  1008.       case 'G':
  1009.       if (getYesNo("CONFRM") )
  1010.         {
  1011.         terminate( /* hangUp == */ TRUE, TRUE);
  1012.         return;
  1013.         };
  1014.       case 'Q':      done = TRUE;                      break;
  1015.       default:       done = TRUE;                      break;
  1016.  
  1017.       }
  1018.     if (!done) writeSysTab();
  1019.  
  1020.     }
  1021.   while (!done);
  1022.  
  1023.   }
  1024. /**
  1025.  globalreplace()
  1026.  Replace the first delimited string with the second delimited
  1027.  string.  An optional repeat count precedes the 1st delimiter.
  1028.  If a repeat count isn't given, it is assumed to be MAXTEXT+1.
  1029.  The delimiter may be any character except a numeric character.
  1030. **/
  1031. void
  1032. qwkglobalreplace(char *buf, char *qwkold)
  1033.   {
  1034.   #define STRINGSIZE  (4*SECTSIZE)
  1035.   char       *p,
  1036.   *bufend,
  1037.   delim,
  1038.   *old,
  1039.   *new;
  1040.   int       i,
  1041.   cnt,
  1042.   oldlen,
  1043.   newlen,
  1044.   diff;
  1045.   if (!*qwkold)
  1046.   return;       /* Quit if no string  */
  1047.   cnt = (int) atoi(qwkold);
  1048.   if (!cnt)
  1049.   cnt = strlen(buf);
  1050.   p = qwkold;
  1051.   while (isdigit(*p))   /* Skip over the count if any  */
  1052.   p++;
  1053.   delim = *p;
  1054.   new = strchr(old = ++p, delim) + 1;
  1055.   p = strchr(new, delim);
  1056.   new[-1] =     /* Terminate old string  */
  1057.   *p = 0;       /* Terminate new string  */
  1058.   newlen = strlen(new);
  1059.   oldlen = strlen(old);
  1060.   diff = newlen - oldlen;
  1061.   if (!*old)return;  /*  keep dolts from entering a  */
  1062.                      /*   NULL as the search string.  */
  1063.   for (p = buf, i = cnt; bufend = buf + strlen(buf), p < bufend && i &&
  1064.   onLine() && !outFlag; p += newlen, i--)
  1065.     {
  1066.     p = matchString(p, old, bufend);
  1067.     if (!p)
  1068.     break;
  1069.     if (newlen > oldlen && diff >= (MAXTEXT - strlen(buf) - 1))
  1070.       {
  1071.       /*
  1072.       * mPrintf(" Buffer Full\n ");
  1073.       */
  1074.       break;
  1075.  
  1076.       }
  1077.     crtColumn = 1;
  1078.     /*
  1079.     * mPrintf("%4d\b\b\b\b", cnt-i);
  1080.     */
  1081.   /*  replace(p, new, oldlen, newlen); */
  1082.  
  1083.     }
  1084.   outFlag = OUTOK;
  1085.   /*
  1086.   * mPrintf(" Replaced %d", cnt -i);
  1087.  doCR();
  1088.   */
  1089.  
  1090.   }
  1091. /**
  1092.  qwkReadDate()
  1093.  This function interprets the citadel date string and returns a
  1094.  QWK formatted date string.
  1095. **/
  1096. void
  1097. qwkReadDate(char *date, char *datestr)
  1098.   {
  1099.   int       rover,
  1100.   found;
  1101.   int       year,
  1102.   month,
  1103.   day;
  1104.   label     mon;
  1105.   if (!date[0])
  1106.     {
  1107.     year = 90;
  1108.     month = 1;
  1109.     day = 1;
  1110.  
  1111.     }
  1112.   else
  1113.     {
  1114.     if (!isdigit(date[0]))
  1115.       {
  1116.       year = 90;
  1117.       month = 1;
  1118.       day = 1;
  1119.  
  1120.       }
  1121.     else
  1122.       {
  1123.       year = atoi(date);
  1124.       while (isdigit(*date))
  1125.       date++;
  1126.       for (rover = 0; isalpha(*date); date++, rover++)
  1127.       mon[rover] = toUpper(*date);
  1128.       mon[rover] = 0;
  1129.       if (rover == 0)
  1130.         {
  1131.         year = 90;
  1132.         month = 1;
  1133.         day = 1;
  1134.  
  1135.         }
  1136.       else
  1137.         {
  1138.         for (found = rover = 0; rover < NumElems(MonthTab); rover++)
  1139.         if (strncmp(mon, MonthTab[rover], strLen(mon)) == SAMESTRING)
  1140.           {
  1141.           found++;
  1142.           month = rover + 1;
  1143.  
  1144.           }
  1145.         if (found != 1)
  1146.         month = 1;
  1147.         if ((day = atoi(date)) == 0)
  1148.         day = 1;
  1149.  
  1150.         }
  1151.  
  1152.       }
  1153.  
  1154.     }
  1155.   sprintf(datestr, "%02d-%02d-%02d", month, day, year);
  1156.   return;
  1157.  
  1158.   }
  1159. /**
  1160.  
  1161. qwkReadTime()
  1162.  
  1163. This function interprets the citadel time string and returns a
  1164. QWK formatted time string.
  1165.  
  1166. **/
  1167. void
  1168. qwkReadTime(char *time, char *timestr)
  1169.   {
  1170.   int   hours,  minutes;
  1171.   if (!time[0])
  1172.     {
  1173.     hours = 00;
  1174.     minutes = 00;
  1175.  
  1176.     }
  1177.   else
  1178.     {
  1179.     if (!isdigit(time[0]))
  1180.       {
  1181.       hours = 00;
  1182.       minutes = 00;
  1183.  
  1184.       }
  1185.     else
  1186.       {
  1187.       hours = atoi(time);
  1188.       while (isdigit(*time))
  1189.       time++;
  1190.       time++;
  1191.       minutes = atoi(time);
  1192.       while (isdigit(*time))
  1193.       time++;
  1194.       if (strchr(time, 'P') || strchr(time, 'p'))
  1195.       hours += 12;
  1196.  
  1197.       }
  1198.  
  1199.     }
  1200.   sprintf(timestr, "%02d:%02d", hours, minutes);
  1201.   return;
  1202.  
  1203.   }
  1204. /**
  1205.  
  1206. RepReadDate()
  1207.  
  1208. This function interprets the QWK REP date string and returns a
  1209. Citadel formatted date string.
  1210.  
  1211. **/
  1212. void
  1213. RepReadDate(char *date, char *datestr)
  1214.   {
  1215.   char     *monthTab[13] =
  1216.     {
  1217.     "", "Jan", "Feb", "Mar",
  1218.     "Apr", "May", "Jun",
  1219.     "Jul", "Aug", "Sep",
  1220.     "Oct", "Nov", "Dec"
  1221.  
  1222.     };
  1223.   int       year,  month,  day;
  1224.   if (!isdigit(date[0]))
  1225.     {
  1226.     year = 0;
  1227.     month = 0;
  1228.     day = 0;
  1229.     }
  1230.   else
  1231.     {
  1232.     month = atoi(date);
  1233.     while (isdigit(*date))      date++;
  1234.     date++;
  1235.     day = atoi(date);
  1236.     while (isdigit(*date))      date++;
  1237.     date++;
  1238.     year = atoi(date);
  1239.     };
  1240.   if (year != 0 && month != 0 && day != 0)
  1241.     sprintf(datestr, "%02d%3s%02d", year, monthTab[month - 1], day);
  1242.   else
  1243.     datestr[0] = NULL;
  1244.   return;
  1245.   }
  1246.  
  1247. /**
  1248.  
  1249. RepReadTime()
  1250.  
  1251. This function interprets the QWK REP time string and returns a
  1252. Citadel formatted time string.
  1253.  
  1254. **/
  1255. void
  1256. RepReadTime(char *time, char *timestr)
  1257.   {
  1258.   int     hours,  minutes;
  1259.   if (!time[0])
  1260.     {
  1261.     hours = 00;
  1262.     minutes = 00;
  1263.  
  1264.     }
  1265.   else
  1266.     {
  1267.     if (!isdigit(time[0]))
  1268.       {
  1269.       hours = 00;
  1270.       minutes = 00;
  1271.  
  1272.       }
  1273.     else
  1274.       {
  1275.       hours = atoi(time);
  1276.       while (isdigit(*time))
  1277.       time++;
  1278.       time++;
  1279.       minutes = atoi(time);
  1280.       while (isdigit(*time))
  1281.       time++;
  1282.  
  1283.       }
  1284.  
  1285.     }
  1286.   if (hours != 0 && minutes != 0)
  1287.   sprintf(timestr, "%02d:%02d %s", (hours > 12) ? hours - 12 : hours,
  1288.   minutes, (hours > 12) ? "pm" : "am");
  1289.   else
  1290.   timestr[0] = NULL;
  1291.   return;
  1292.  
  1293.   }
  1294. /**
  1295.  
  1296. ResetRooms()
  1297.  
  1298. This function is a menu system for selecting and reseting message
  1299. pointers for QWK packets.
  1300. **/
  1301.  
  1302. void
  1303. ResetRooms()
  1304.   {
  1305.   char      done = FALSE;
  1306.   char      letter1;
  1307.   int       rover;
  1308.   long      offset;
  1309.   outFlag = OUTOK;
  1310.   do
  1311.     {
  1312.     Output_Citadel_Message("QWKRSM", NULL, NULL, NULL);
  1313.     letter1 = toUpper(iChar());
  1314.     mPrintf("\n ");
  1315.     switch (letter1)
  1316.       {
  1317.       case '0':
  1318.       for (rover = 0; rover < MAXROOMS; rover++)
  1319.         {
  1320.         QwkRooms[rover].LastMessageNo = 0l;
  1321.  
  1322.         }
  1323.       break;
  1324.       case '1':
  1325.       for (rover = 0; rover < MAXROOMS; rover++)
  1326.         {
  1327.         QwkRooms[rover].LastMessageNo = cfg.newest;
  1328.  
  1329.         }
  1330.       break;
  1331.       case '2':
  1332.       for (rover = 0; rover < MAXROOMS; rover++)
  1333.         {
  1334.         QwkRooms[rover].LastMessageNo =
  1335.         QwkRooms[rover].OldLastMessageNo;
  1336.  
  1337.         }
  1338.       break;
  1339.       case '3':
  1340.       for (rover = 0; rover < MAXROOMS; rover++)
  1341.         {
  1342.         QwkRooms[rover].LastMessageNo =
  1343.         logBuf.lbvisit[logBuf.lbgen[rover] & CALLMASK];
  1344.  
  1345.         }
  1346.       break;
  1347.       case '4':
  1348.       offset = getNumber("QWKNML", 1, cfg.MsgsPerrm);
  1349.       for (rover = 0; rover < MAXROOMS; rover++)
  1350.         {
  1351.         QwkRooms[rover].LastMessageNo =
  1352.         roomTab[rover].rtlastMessage - offset;
  1353.  
  1354.         }
  1355.       break;
  1356.       case '5':
  1357.       mPrintf("not active at this time\n ");
  1358.       break;
  1359.       case 'Q':
  1360.       done = TRUE;
  1361.       break;
  1362.       case 'H':
  1363.       default:
  1364.       Output_Citadel_Message("QWKRSH",NULL, NULL, NULL);
  1365.       break;
  1366.  
  1367.       }
  1368.  
  1369.     }
  1370.   while (!done);
  1371.   return;
  1372.  
  1373.   }
  1374. /**
  1375.  
  1376. ArchQWK()
  1377.  
  1378. This function will archive all files from the QWKworkarea using
  1379. whatever archiving method the BBS supports and the user has
  1380. selected.  It will then return the size of the resulting file.
  1381.  
  1382. **/
  1383. long
  1384. ArchQWK()
  1385.   {
  1386.   FILE     *fbuf;
  1387.   char      tempStr[20],
  1388.   tempstr[30];
  1389.   long      fileSize = 0l;
  1390.   sprintf(tempStr, "%s.qwk", cfg.QwkName.saDirname);
  1391.   makeSysName(tempname, tempStr, &cfg.QwkWorkArea);
  1392.   strcpy(tempstr, "*.*");
  1393.   makeSysName(tempFile, tempstr, &cfg.QwkWorkArea);
  1394.   Compress(qwkdef.Archiver, tempFile, tempname);
  1395.   if ((fbuf = safeopen(tempname, READ_ANY)) != NULL)
  1396.     {
  1397.     totalBytes(&fileSize, fbuf);
  1398.     fclose(fbuf);
  1399.  
  1400.     }
  1401.   /*
  1402.   * printf("ArchQWK C1: %u, %s\n", fileSize, tempname); iChar();
  1403.   */
  1404.   return fileSize;
  1405.  
  1406.   }
  1407. /**
  1408.  CleanUpPacket()
  1409. This function deletes all files created in the QWKworkarea after
  1410. a packet is processed, good or bad.  If the USER is at the console
  1411. then it will move the files to a destination instead.
  1412. **/
  1413. void
  1414. CleanUpPacket()
  1415.   {
  1416.   char      tempstr[30],
  1417.   tempstr2[100];
  1418.   int       rover;
  1419.   strcpy(tempstr2, (char *)&cfg.QwkWorkArea.saDirname);
  1420.   rover = strlen(tempstr2);
  1421.   tempstr2[rover - 1] = NULL;
  1422.   /**
  1423.     printf("%s\n", tempstr2);
  1424.   **/
  1425.   if (chdir(tempstr2) != 0) printf("chdir failed!\n");
  1426.   /**
  1427.     printf("%s\n", getcwd(NULL, 100));
  1428.    iChar();
  1429.   **/
  1430.   getcwd(tempstr2, 100);
  1431.   printf("Current Directory: %s\n ", tempstr2);
  1432.   for (rover = 0; rover < MAXROOMS; rover++)
  1433.     {
  1434.     if (UsedQwkRooms[rover].messagesfound != 0)
  1435.       {
  1436.       sprintf(tempstr, "%03d.ndx", rover);
  1437.       unlink(tempstr);
  1438.  
  1439.       }
  1440.  
  1441.     }
  1442.   strcpy(tempstr, "personal.ndx");
  1443.   unlink(tempstr);
  1444.   sprintf(tempstr, "messages.dat");
  1445.   unlink(tempstr);
  1446.   sprintf(tempstr, "control.dat");
  1447.   unlink(tempstr);
  1448.   sprintf(tempstr, "%s.qwk", cfg.QwkName.saDirname);
  1449.   printf("removing used packet:%s\n",tempstr);
  1450.   unlink(tempstr);
  1451.  
  1452.   }
  1453. /*
  1454. *
  1455. * This gets all set up to do something with a message.  We use this rather
  1456. * than the findMessage in libmsg.c so we can automatically read in the 'M'
  1457. * field.
  1458. */
  1459. extern struct mBuf mFile1;
  1460. extern FILE        *msgfl;
  1461.  
  1462.  
  1463. char Process_Current_Message(loc, id)
  1464. SECTOR_ID  loc;         /* sector in message.buf */
  1465. MSG_NUMBER id;          /* unique-for-some-time ID# */
  1466.   {
  1467.   MSG_NUMBER here;
  1468.   startAt(msgfl, &mFile1, loc, 0);
  1469.   do
  1470.     {
  1471.     getMessage(getMsgChar, FALSE, TRUE, TRUE);
  1472.     here = atol(msgBuf.mbId);
  1473.  
  1474.     }
  1475.   while (here != id &&  mFile1.thisSector == loc);
  1476.   return (char) ((here == id));
  1477.  
  1478.   }
  1479.  
  1480. union Conv_Union
  1481. {
  1482.     unsigned char       uc[4];
  1483.     unsigned short int  ui[2];
  1484.     float               f[1];
  1485. };
  1486. /**
  1487.   MSBIN.C - MSBIN-IEEE/IEEE-MSBIN conversion routines.
  1488. **/
  1489.  
  1490. /**
  1491.   FloatToMSB() - Convert a IEEE floating point number to MSBIN format.
  1492.  
  1493.   Arguments : (float f) Number to be converted.
  1494.   Returns   : (float) Same number in MSBIN format.
  1495.   Notes     : Routine courtsey of Jefferey Foy, Modified by J. Dawson
  1496. **/
  1497. float FloatToMSB(float f)
  1498. {
  1499.     union Conv_Union t;
  1500.     short int sign, exp;
  1501.  
  1502.     t.f[0] = f;
  1503.  
  1504.     sign = t.uc[0] / 0x80;
  1505.     exp  = ((t.ui[0] >> 7) - 0x7F + 0x81) & 0xFF;
  1506.     t.ui[0] = (t.ui[0] & 0x7F) | (sign << 7) | (exp << 8);
  1507.  
  1508.     return(t.f[0]);
  1509. }
  1510.  
  1511. /**
  1512.   MSBToFloat() - Convert a MSBIN into IEEE floating point.
  1513.  
  1514.   Arguments   : (float f) Number to be converted.
  1515.   Returns     : (float) Same number in IEEE floating point.
  1516.   Notes       : Routine courtsey of Jeffery Foy, Modified by Jim Dawson
  1517. **/
  1518.  
  1519. float MSBtoFloat(float f)
  1520. {
  1521.     union Conv_Union t;
  1522.     short int sign, exp;
  1523.  
  1524.     t.f[0] = f;
  1525.  
  1526.     sign = t.uc[1] / 0x80;
  1527.     exp  = (t.uc[0] - 0x81 + 0x7F) & 0xFF;
  1528.  
  1529.     t.ui[0] = (t.ui[0] & 0x7f) | (exp << 7)| (sign << 15);
  1530.     return(t.f[0]);
  1531. }
  1532.